package com.jilefojing.service.impl;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

import com.jilefojing.beans.data.enums.ResponseEnum;
import com.jilefojing.beans.enums.ItemTypeEnumForSource;
import com.jilefojing.beans.enums.ProgressStatusForSource;
import com.jilefojing.beans.enums.StatusEnumForPublish;
import com.jilefojing.beans.exception.UserContextException;
import com.jilefojing.beans.pojos.RCategorySource;
import com.jilefojing.beans.pojos.base.BasePo;
import com.jilefojing.beans.pojos.enhanced.EnhancedDCategory;
import com.jilefojing.beans.pojos.enhanced.EnhancedRCategorySource;
import com.jilefojing.beans.pojos.enhanced.EnhancedUser;
import com.jilefojing.beans.pojos.enhanced.base.BaseEnhanced;
import com.jilefojing.beans.query.RCategorySourceQuery;
import com.jilefojing.beans.query.RCategorySourceQuery.IntersectionCategory;
import com.jilefojing.beans.vo.Pagination;
import com.jilefojing.context.beans.vo.UserContext;
import com.jilefojing.dao.IRCategorySourceDao;
import com.jilefojing.service.IDCategoryService;
import com.jilefojing.service.IRCategorySourceService;
import com.jilefojing.service.ISourceService;
import com.jilefojing.service.IUserService;
import com.jilefojing.service.base.impl.BaseService;
import com.jilefojing.util.CombinationUtil;
import com.jilefojing.util.Detect;

/**
 * 
 * @author 作者 jgshun
 * @date 创建时间 2016年07月26日 16时40分30秒
 */
@Service
public class RCategorySourceService extends BaseService<RCategorySource> implements IRCategorySourceService {
	private static final Logger _LOGGER = LoggerFactory.getLogger(RCategorySourceService.class);

	@Autowired
	private IRCategorySourceDao rCategorySourceDao;
	@Autowired
	private IDCategoryService dCategoryService;
	@Autowired
	private IUserService userService;
	@Autowired
	private ISourceService sourceService;
	@Autowired
	private ApplicationContext applicationContext;

	@Override
	public Pagination<EnhancedRCategorySource> getPagination(RCategorySourceQuery rCategorySourceQuery, Pagination<EnhancedRCategorySource> pagination, UserContext userContext) {
		@SuppressWarnings("unchecked")
		Pagination<RCategorySource> rCategorySourcePagination = rCategorySourceDao.getPagination(rCategorySourceQuery, pagination.copy());
		pagination.setCount(rCategorySourcePagination.getCount());
		if (!Detect.notEmpty(rCategorySourcePagination.getItems())) {
			return pagination;
		}
		pagination.setItems(this.convent2Enhanceds(rCategorySourcePagination.getItems()));

		this.appendEnhancedCommons(pagination.getItems(), userContext);

		return pagination;
	}

	@Override
	public List<EnhancedRCategorySource> appendEnhancedCommons(List<? extends BaseEnhanced> enhancedItems, UserContext userContext) {
		@SuppressWarnings("unchecked")
		List<EnhancedRCategorySource> enhancedRCategorySources = (List<EnhancedRCategorySource>) enhancedItems;
		this.appendEnhancedItem(enhancedRCategorySources, userContext);
		this.appendEnhancedDCategories(enhancedRCategorySources, userContext);
		this.appendEnhancedUsers(enhancedRCategorySources, userContext);
		return enhancedRCategorySources;
	}

	@Override
	public EnhancedRCategorySource appendEnhancedUsers(EnhancedRCategorySource enhancedRCategorySource, UserContext userContext) {
		this.appendEnhancedUsers(Arrays.asList(new EnhancedRCategorySource[] { enhancedRCategorySource }), userContext);
		return enhancedRCategorySource;
	}

	@Override
	public List<EnhancedRCategorySource> appendEnhancedUsers(List<EnhancedRCategorySource> enhancedRCategorySources, UserContext userContext) {
		List<Long> userIds = new ArrayList<Long>();
		for (EnhancedRCategorySource _EnhancedRCategorySource : enhancedRCategorySources) {
			if (_EnhancedRCategorySource.getEnhancedUser() != null) {
				userIds.add(_EnhancedRCategorySource.getEnhancedUser().getId());
			}
		}
		if (!Detect.notEmpty(userIds)) {
			return enhancedRCategorySources;
		}
		List<EnhancedUser> enhancedUsers = userService.getEnhancedUsers(userIds);
		if (!Detect.notEmpty(enhancedUsers)) {
			return enhancedRCategorySources;
		}

		for (EnhancedRCategorySource _EnhancedRCategorySource : enhancedRCategorySources) {
			if (_EnhancedRCategorySource.getEnhancedUser() != null) {
				for (EnhancedUser _EnhancedUser : enhancedUsers) {
					if (_EnhancedRCategorySource.getEnhancedUser().getId() == _EnhancedUser.getId()) {
						_EnhancedRCategorySource.setEnhancedUser(_EnhancedUser);
						break;
					}
				}
			}
		}

		return enhancedRCategorySources;
	}

	@Override
	public EnhancedRCategorySource appendEnhancedDCategories(EnhancedRCategorySource enhancedRCategorySource, UserContext userContext) {
		this.appendEnhancedDCategories(Arrays.asList(new EnhancedRCategorySource[] { enhancedRCategorySource }), userContext);
		return enhancedRCategorySource;
	}

	@Override
	public List<EnhancedRCategorySource> appendEnhancedDCategories(List<EnhancedRCategorySource> enhancedRCategorySources, UserContext userContext) {
		Set<Long> categoryIds = new HashSet<Long>();

		for (EnhancedRCategorySource _EnhancedRCategorySource : enhancedRCategorySources) {
			if (_EnhancedRCategorySource.getEnhancedC1Category() != null) {
				categoryIds.add(_EnhancedRCategorySource.getEnhancedC1Category().getId());
			}
			if (_EnhancedRCategorySource.getEnhancedC2Category() != null) {
				categoryIds.add(_EnhancedRCategorySource.getEnhancedC2Category().getId());
			}
			if (_EnhancedRCategorySource.getEnhancedC3Category() != null) {
				categoryIds.add(_EnhancedRCategorySource.getEnhancedC3Category().getId());
			}
			if (_EnhancedRCategorySource.getEnhancedC4Category() != null) {
				categoryIds.add(_EnhancedRCategorySource.getEnhancedC4Category().getId());
			}
			if (_EnhancedRCategorySource.getEnhancedC5Category() != null) {
				categoryIds.add(_EnhancedRCategorySource.getEnhancedC5Category().getId());
			}
			if (_EnhancedRCategorySource.getEnhancedC6Category() != null) {
				categoryIds.add(_EnhancedRCategorySource.getEnhancedC6Category().getId());
			}
			if (_EnhancedRCategorySource.getEnhancedC7Category() != null) {
				categoryIds.add(_EnhancedRCategorySource.getEnhancedC7Category().getId());
			}
			if (_EnhancedRCategorySource.getEnhancedC8Category() != null) {
				categoryIds.add(_EnhancedRCategorySource.getEnhancedC8Category().getId());
			}
			if (_EnhancedRCategorySource.getEnhancedC9Category() != null) {
				categoryIds.add(_EnhancedRCategorySource.getEnhancedC9Category().getId());
			}
			if (_EnhancedRCategorySource.getEnhancedC10Category() != null) {
				categoryIds.add(_EnhancedRCategorySource.getEnhancedC10Category().getId());
			}
			if (_EnhancedRCategorySource.getEnhancedC11Category() != null) {
				categoryIds.add(_EnhancedRCategorySource.getEnhancedC11Category().getId());
			}
			if (_EnhancedRCategorySource.getEnhancedC12Category() != null) {
				categoryIds.add(_EnhancedRCategorySource.getEnhancedC12Category().getId());
			}
			if (_EnhancedRCategorySource.getEnhancedC13Category() != null) {
				categoryIds.add(_EnhancedRCategorySource.getEnhancedC13Category().getId());
			}
			if (_EnhancedRCategorySource.getEnhancedC14Category() != null) {
				categoryIds.add(_EnhancedRCategorySource.getEnhancedC14Category().getId());
			}
			if (_EnhancedRCategorySource.getEnhancedC15Category() != null) {
				categoryIds.add(_EnhancedRCategorySource.getEnhancedC15Category().getId());
			}
			if (_EnhancedRCategorySource.getEnhancedC16Category() != null) {
				categoryIds.add(_EnhancedRCategorySource.getEnhancedC16Category().getId());
			}
			if (_EnhancedRCategorySource.getEnhancedC17Category() != null) {
				categoryIds.add(_EnhancedRCategorySource.getEnhancedC17Category().getId());
			}
			if (_EnhancedRCategorySource.getEnhancedC18Category() != null) {
				categoryIds.add(_EnhancedRCategorySource.getEnhancedC18Category().getId());
			}
			if (_EnhancedRCategorySource.getEnhancedC19Category() != null) {
				categoryIds.add(_EnhancedRCategorySource.getEnhancedC19Category().getId());
			}
			if (_EnhancedRCategorySource.getEnhancedC20Category() != null) {
				categoryIds.add(_EnhancedRCategorySource.getEnhancedC20Category().getId());
			}
			if (_EnhancedRCategorySource.getEnhancedC21Category() != null) {
				categoryIds.add(_EnhancedRCategorySource.getEnhancedC21Category().getId());
			}
			if (_EnhancedRCategorySource.getEnhancedC22Category() != null) {
				categoryIds.add(_EnhancedRCategorySource.getEnhancedC22Category().getId());
			}
			if (_EnhancedRCategorySource.getEnhancedC23Category() != null) {
				categoryIds.add(_EnhancedRCategorySource.getEnhancedC23Category().getId());
			}
			if (_EnhancedRCategorySource.getEnhancedC24Category() != null) {
				categoryIds.add(_EnhancedRCategorySource.getEnhancedC24Category().getId());
			}
			if (_EnhancedRCategorySource.getEnhancedC25Category() != null) {
				categoryIds.add(_EnhancedRCategorySource.getEnhancedC25Category().getId());
			}
			if (_EnhancedRCategorySource.getEnhancedC26Category() != null) {
				categoryIds.add(_EnhancedRCategorySource.getEnhancedC26Category().getId());
			}
			if (_EnhancedRCategorySource.getEnhancedC27Category() != null) {
				categoryIds.add(_EnhancedRCategorySource.getEnhancedC27Category().getId());
			}
			if (_EnhancedRCategorySource.getEnhancedC28Category() != null) {
				categoryIds.add(_EnhancedRCategorySource.getEnhancedC28Category().getId());
			}
			if (_EnhancedRCategorySource.getEnhancedC29Category() != null) {
				categoryIds.add(_EnhancedRCategorySource.getEnhancedC29Category().getId());
			}
			if (_EnhancedRCategorySource.getEnhancedC30Category() != null) {
				categoryIds.add(_EnhancedRCategorySource.getEnhancedC30Category().getId());
			}
			if (_EnhancedRCategorySource.getEnhancedC31Category() != null) {
				categoryIds.add(_EnhancedRCategorySource.getEnhancedC31Category().getId());
			}
			if (_EnhancedRCategorySource.getEnhancedC32Category() != null) {
				categoryIds.add(_EnhancedRCategorySource.getEnhancedC32Category().getId());
			}
			if (_EnhancedRCategorySource.getEnhancedC33Category() != null) {
				categoryIds.add(_EnhancedRCategorySource.getEnhancedC33Category().getId());
			}

			// TODO 可以继续增加 资源类别
		}
		if (!Detect.notEmpty(categoryIds)) {
			return enhancedRCategorySources;
		}
		List<EnhancedDCategory> enhancedDCategories = dCategoryService.getEnhancedDCategories(new ArrayList<Long>(categoryIds), userContext);
		if (!Detect.notEmpty(enhancedDCategories)) {
			return enhancedRCategorySources;
		}

		for (EnhancedRCategorySource _EnhancedRCategorySource : enhancedRCategorySources) {
			for (EnhancedDCategory _EnhancedDCategory : enhancedDCategories) {
				if (_EnhancedRCategorySource.getEnhancedC1Category() != null && _EnhancedRCategorySource.getEnhancedC1Category().getId() == _EnhancedDCategory.getId()) {
					_EnhancedRCategorySource.setEnhancedC1Category(_EnhancedDCategory);
				}
				if (_EnhancedRCategorySource.getEnhancedC2Category() != null && _EnhancedRCategorySource.getEnhancedC2Category().getId() == _EnhancedDCategory.getId()) {
					_EnhancedRCategorySource.setEnhancedC2Category(_EnhancedDCategory);
				}
				if (_EnhancedRCategorySource.getEnhancedC3Category() != null && _EnhancedRCategorySource.getEnhancedC3Category().getId() == _EnhancedDCategory.getId()) {
					_EnhancedRCategorySource.setEnhancedC3Category(_EnhancedDCategory);
				}
				if (_EnhancedRCategorySource.getEnhancedC4Category() != null && _EnhancedRCategorySource.getEnhancedC4Category().getId() == _EnhancedDCategory.getId()) {
					_EnhancedRCategorySource.setEnhancedC4Category(_EnhancedDCategory);
				}
				if (_EnhancedRCategorySource.getEnhancedC5Category() != null && _EnhancedRCategorySource.getEnhancedC5Category().getId() == _EnhancedDCategory.getId()) {
					_EnhancedRCategorySource.setEnhancedC5Category(_EnhancedDCategory);
				}
				if (_EnhancedRCategorySource.getEnhancedC6Category() != null && _EnhancedRCategorySource.getEnhancedC6Category().getId() == _EnhancedDCategory.getId()) {
					_EnhancedRCategorySource.setEnhancedC6Category(_EnhancedDCategory);
				}
				if (_EnhancedRCategorySource.getEnhancedC7Category() != null && _EnhancedRCategorySource.getEnhancedC7Category().getId() == _EnhancedDCategory.getId()) {
					_EnhancedRCategorySource.setEnhancedC7Category(_EnhancedDCategory);
				}
				if (_EnhancedRCategorySource.getEnhancedC8Category() != null && _EnhancedRCategorySource.getEnhancedC8Category().getId() == _EnhancedDCategory.getId()) {
					_EnhancedRCategorySource.setEnhancedC8Category(_EnhancedDCategory);
				}
				if (_EnhancedRCategorySource.getEnhancedC9Category() != null && _EnhancedRCategorySource.getEnhancedC9Category().getId() == _EnhancedDCategory.getId()) {
					_EnhancedRCategorySource.setEnhancedC9Category(_EnhancedDCategory);
				}
				if (_EnhancedRCategorySource.getEnhancedC10Category() != null && _EnhancedRCategorySource.getEnhancedC10Category().getId() == _EnhancedDCategory.getId()) {
					_EnhancedRCategorySource.setEnhancedC10Category(_EnhancedDCategory);
				}
				if (_EnhancedRCategorySource.getEnhancedC11Category() != null && _EnhancedRCategorySource.getEnhancedC11Category().getId() == _EnhancedDCategory.getId()) {
					_EnhancedRCategorySource.setEnhancedC11Category(_EnhancedDCategory);
				}
				if (_EnhancedRCategorySource.getEnhancedC12Category() != null && _EnhancedRCategorySource.getEnhancedC12Category().getId() == _EnhancedDCategory.getId()) {
					_EnhancedRCategorySource.setEnhancedC12Category(_EnhancedDCategory);
				}
				if (_EnhancedRCategorySource.getEnhancedC13Category() != null && _EnhancedRCategorySource.getEnhancedC13Category().getId() == _EnhancedDCategory.getId()) {
					_EnhancedRCategorySource.setEnhancedC13Category(_EnhancedDCategory);
				}
				if (_EnhancedRCategorySource.getEnhancedC14Category() != null && _EnhancedRCategorySource.getEnhancedC14Category().getId() == _EnhancedDCategory.getId()) {
					_EnhancedRCategorySource.setEnhancedC14Category(_EnhancedDCategory);
				}
				if (_EnhancedRCategorySource.getEnhancedC15Category() != null && _EnhancedRCategorySource.getEnhancedC15Category().getId() == _EnhancedDCategory.getId()) {
					_EnhancedRCategorySource.setEnhancedC15Category(_EnhancedDCategory);
				}
				if (_EnhancedRCategorySource.getEnhancedC16Category() != null && _EnhancedRCategorySource.getEnhancedC16Category().getId() == _EnhancedDCategory.getId()) {
					_EnhancedRCategorySource.setEnhancedC16Category(_EnhancedDCategory);
				}
				if (_EnhancedRCategorySource.getEnhancedC17Category() != null && _EnhancedRCategorySource.getEnhancedC17Category().getId() == _EnhancedDCategory.getId()) {
					_EnhancedRCategorySource.setEnhancedC17Category(_EnhancedDCategory);
				}
				if (_EnhancedRCategorySource.getEnhancedC18Category() != null && _EnhancedRCategorySource.getEnhancedC18Category().getId() == _EnhancedDCategory.getId()) {
					_EnhancedRCategorySource.setEnhancedC18Category(_EnhancedDCategory);
				}
				if (_EnhancedRCategorySource.getEnhancedC19Category() != null && _EnhancedRCategorySource.getEnhancedC19Category().getId() == _EnhancedDCategory.getId()) {
					_EnhancedRCategorySource.setEnhancedC19Category(_EnhancedDCategory);
				}
				if (_EnhancedRCategorySource.getEnhancedC20Category() != null && _EnhancedRCategorySource.getEnhancedC20Category().getId() == _EnhancedDCategory.getId()) {
					_EnhancedRCategorySource.setEnhancedC20Category(_EnhancedDCategory);
				}
				if (_EnhancedRCategorySource.getEnhancedC21Category() != null && _EnhancedRCategorySource.getEnhancedC21Category().getId() == _EnhancedDCategory.getId()) {
					_EnhancedRCategorySource.setEnhancedC21Category(_EnhancedDCategory);
				}
				if (_EnhancedRCategorySource.getEnhancedC22Category() != null && _EnhancedRCategorySource.getEnhancedC22Category().getId() == _EnhancedDCategory.getId()) {
					_EnhancedRCategorySource.setEnhancedC22Category(_EnhancedDCategory);
				}
				if (_EnhancedRCategorySource.getEnhancedC23Category() != null && _EnhancedRCategorySource.getEnhancedC23Category().getId() == _EnhancedDCategory.getId()) {
					_EnhancedRCategorySource.setEnhancedC23Category(_EnhancedDCategory);
				}
				if (_EnhancedRCategorySource.getEnhancedC24Category() != null && _EnhancedRCategorySource.getEnhancedC24Category().getId() == _EnhancedDCategory.getId()) {
					_EnhancedRCategorySource.setEnhancedC24Category(_EnhancedDCategory);
				}
				if (_EnhancedRCategorySource.getEnhancedC25Category() != null && _EnhancedRCategorySource.getEnhancedC25Category().getId() == _EnhancedDCategory.getId()) {
					_EnhancedRCategorySource.setEnhancedC25Category(_EnhancedDCategory);
				}
				if (_EnhancedRCategorySource.getEnhancedC26Category() != null && _EnhancedRCategorySource.getEnhancedC26Category().getId() == _EnhancedDCategory.getId()) {
					_EnhancedRCategorySource.setEnhancedC26Category(_EnhancedDCategory);
				}
				if (_EnhancedRCategorySource.getEnhancedC27Category() != null && _EnhancedRCategorySource.getEnhancedC27Category().getId() == _EnhancedDCategory.getId()) {
					_EnhancedRCategorySource.setEnhancedC27Category(_EnhancedDCategory);
				}
				if (_EnhancedRCategorySource.getEnhancedC28Category() != null && _EnhancedRCategorySource.getEnhancedC28Category().getId() == _EnhancedDCategory.getId()) {
					_EnhancedRCategorySource.setEnhancedC28Category(_EnhancedDCategory);
				}
				if (_EnhancedRCategorySource.getEnhancedC29Category() != null && _EnhancedRCategorySource.getEnhancedC29Category().getId() == _EnhancedDCategory.getId()) {
					_EnhancedRCategorySource.setEnhancedC29Category(_EnhancedDCategory);
				}
				if (_EnhancedRCategorySource.getEnhancedC30Category() != null && _EnhancedRCategorySource.getEnhancedC30Category().getId() == _EnhancedDCategory.getId()) {
					_EnhancedRCategorySource.setEnhancedC30Category(_EnhancedDCategory);
				}
				if (_EnhancedRCategorySource.getEnhancedC31Category() != null && _EnhancedRCategorySource.getEnhancedC31Category().getId() == _EnhancedDCategory.getId()) {
					_EnhancedRCategorySource.setEnhancedC31Category(_EnhancedDCategory);
				}
				if (_EnhancedRCategorySource.getEnhancedC32Category() != null && _EnhancedRCategorySource.getEnhancedC32Category().getId() == _EnhancedDCategory.getId()) {
					_EnhancedRCategorySource.setEnhancedC32Category(_EnhancedDCategory);
				}
				if (_EnhancedRCategorySource.getEnhancedC33Category() != null && _EnhancedRCategorySource.getEnhancedC33Category().getId() == _EnhancedDCategory.getId()) {
					_EnhancedRCategorySource.setEnhancedC33Category(_EnhancedDCategory);
				}
				// TODO 可以继续增加 资源类别
			}
		}
		return enhancedRCategorySources;
	}

	@Override
	public Pagination<EnhancedRCategorySource> getPaginationByCategoryIdsForIntersection(List<Long> categoryIds, List<StatusEnumForPublish> statuses, List<ItemTypeEnumForSource> returnItemTypes,
			List<ProgressStatusForSource> progressStatuses, Pagination<EnhancedRCategorySource> pagination, UserContext userContext) {
		// List<IntersectionCategory> intersectionCategories =
		// this.getIntersectionCategories(categoryIds, returnItemTypes,
		// userContext);

		List<String> intersectionCategoryConditions = this.getIntersectionCategoryConditions(categoryIds, returnItemTypes, userContext);

		@SuppressWarnings("unchecked")
		Pagination<RCategorySource> rCategorySourcePagination = rCategorySourceDao.getPaginationByCategoryIdsForIntersection(intersectionCategoryConditions, statuses, returnItemTypes,
				progressStatuses, pagination.copy());
		pagination.setCount(rCategorySourcePagination.getCount());
		if (!Detect.notEmpty(rCategorySourcePagination.getItems())) {
			return pagination;
		}
		pagination.setItems(this.convent2Enhanceds(rCategorySourcePagination.getItems()));
		return pagination;
	}

	private List<String> getIntersectionCategoryConditions(List<Long> categoryIds, List<ItemTypeEnumForSource> returnItemTypes, UserContext userContext) {
		if (!Detect.notEmpty(categoryIds)) {
			return null;
		}
		List<String> resultConditions = new ArrayList<String>();

		List<EnhancedDCategory> useTopEnhancedDCategories = null;
		// 区分出是子分类 还是顶部类
		List<EnhancedDCategory> allEnhancedDCategories = null;
		if (Detect.notEmpty(categoryIds)) {
			allEnhancedDCategories = dCategoryService.getEnhancedDCategories(categoryIds, userContext);
			// 把子分类全部放入顶部分类中
			useTopEnhancedDCategories = this.getUseTopEnhancedDCategories(allEnhancedDCategories);
		} else {
			allEnhancedDCategories = dCategoryService.getEnhancedTopDCategoriesByItemTypes(returnItemTypes, userContext);
			useTopEnhancedDCategories = allEnhancedDCategories;
			dCategoryService.appendEnhancedChildDCategories2EnhancedDCategories(allEnhancedDCategories, userContext);
		}
		resultConditions = this.getResultConditions(useTopEnhancedDCategories);

		// 按照顺序排序组合子分类
		// 根据顺序组合出column的查询条件

		return resultConditions;
	}

	private List<String> getResultConditions(List<EnhancedDCategory> useTopEnhancedDCategories) {
		List<String> ckeys = new ArrayList<String>();
		List<List<Long>> childIdsList = new ArrayList<List<Long>>();

		for (EnhancedDCategory _userTopEnhancedDCategory : useTopEnhancedDCategories) {
			ckeys.add(_userTopEnhancedDCategory.getCkey());
			childIdsList.add(this.getCurChilds(_userTopEnhancedDCategory));
		}

		List<List<Long>> combinations = CombinationUtil.getCombinationResult(childIdsList);
		List<String> resultConditions = new ArrayList<String>();

		if (ckeys.size() == 1) {
			for (List<Long> combination_longs : combinations) {
				for (int i = 0; i < combination_longs.size(); i++) {
					StringBuilder valBud = new StringBuilder();
					valBud.append(" ( ");
					valBud.append("category_").append(ckeys.get(0)).append(" = ").append(combination_longs.get(i));
					valBud.append(" ) ");
					resultConditions.add(valBud.toString());
				}
			}
		} else {
			for (List<Long> combination_longs : combinations) {
				StringBuilder valBud = new StringBuilder();
				valBud.append(" ( ");
				for (int i = 0; i < ckeys.size(); i++) {
					valBud.append("category_").append(ckeys.get(i)).append(" = ").append(combination_longs.get(i));
					if (i < ckeys.size() - 1) {
						valBud.append(" and ");
					}
				}
				valBud.append(" ) ");
				resultConditions.add(valBud.toString());
			}
		}

		return resultConditions;
	}

	private List<EnhancedDCategory> getUseTopEnhancedDCategories(List<EnhancedDCategory> allEnhancedDCategories) {
		List<EnhancedDCategory> useTopEnhancedDCategories = new ArrayList<EnhancedDCategory>();

		List<EnhancedDCategory> topEnhancedDCategories = new ArrayList<EnhancedDCategory>();
		List<EnhancedDCategory> childEnhancedDCategories = new ArrayList<EnhancedDCategory>();

		for (EnhancedDCategory _EnhancedDCategory : allEnhancedDCategories) {
			if (!_EnhancedDCategory.isEntity()) {
				topEnhancedDCategories.add(_EnhancedDCategory);
			} else {
				childEnhancedDCategories.add(_EnhancedDCategory);
			}
		}
		if (Detect.notEmpty(topEnhancedDCategories)) {
			dCategoryService.appendEnhancedChildDCategories2EnhancedDCategories(topEnhancedDCategories, null);
			useTopEnhancedDCategories.addAll(topEnhancedDCategories);
		}
		if (Detect.notEmpty(childEnhancedDCategories)) {
			Map<Long, EnhancedDCategory> _dcsTopMap = new HashMap<Long, EnhancedDCategory>();
			for (EnhancedDCategory _childEnhancedDCategory : childEnhancedDCategories) {
				if (_dcsTopMap.get(_childEnhancedDCategory.getEnhancedParentDCategory().getId()) == null) {
					EnhancedDCategory _topEnhancedDCategory = _childEnhancedDCategory.getEnhancedParentDCategory();
					_topEnhancedDCategory.setCkey(_childEnhancedDCategory.getCkey());

					_dcsTopMap.put(_childEnhancedDCategory.getEnhancedParentDCategory().getId(), _topEnhancedDCategory);
				}
			}
			Collection<EnhancedDCategory> _topEnhancedDCategories = _dcsTopMap.values();
			for (EnhancedDCategory _topEnhancedDCategory : _topEnhancedDCategories) {
				_topEnhancedDCategory.setEnhancedChildDCategories(this.geteEnhancedChildDCategories(_topEnhancedDCategory, childEnhancedDCategories));
			}
			useTopEnhancedDCategories.addAll(_topEnhancedDCategories);
		}
		return useTopEnhancedDCategories;
	}

	private List<EnhancedDCategory> geteEnhancedChildDCategories(EnhancedDCategory topEnhancedDCategory, List<EnhancedDCategory> childEnhancedDCategories) {
		List<EnhancedDCategory> curChildEnhancedDCategories = new ArrayList<EnhancedDCategory>();
		for (EnhancedDCategory _childEnhancedDCategory : childEnhancedDCategories) {
			if (_childEnhancedDCategory.getEnhancedParentDCategory().getId() == topEnhancedDCategory.getId()) {
				curChildEnhancedDCategories.add(_childEnhancedDCategory);
			}
		}
		return curChildEnhancedDCategories;
	}

	private List<IntersectionCategory> getIntersectionCategories2(List<Long> categoryIds, List<ItemTypeEnumForSource> returnItemTypes, UserContext userContext) {

		Set<Long> topIds = null;
		List<EnhancedDCategory> childEnhancedDCategories = null;
		List<IntersectionCategory> intersectionCategories = null;

		if (Detect.notEmpty(categoryIds)) {
			List<EnhancedDCategory> enhancedDCategories = dCategoryService.getEnhancedDCategories(categoryIds, userContext);
			if (Detect.notEmpty(enhancedDCategories)) {
				List<Long> topCategoryIds = new ArrayList<Long>();

				topIds = new HashSet<Long>();
				childEnhancedDCategories = new ArrayList<EnhancedDCategory>();

				for (EnhancedDCategory _EnhancedDCategory : enhancedDCategories) {
					if (_EnhancedDCategory.isEntity()) {
						childEnhancedDCategories.add(_EnhancedDCategory);// 第一步取出所有的子元素
																			// 1
						topIds.add(_EnhancedDCategory.getEnhancedParentDCategory().getId());
					} else {
						topCategoryIds.add(_EnhancedDCategory.getId());
					}
				}
				if (Detect.notEmpty(topCategoryIds)) {
					List<EnhancedDCategory> childEnhancedDCategoriesForTops = dCategoryService.getEnhancedChildDCategoriesByParentIds(topCategoryIds, userContext);
					if (Detect.notEmpty(childEnhancedDCategoriesForTops)) {
						for (EnhancedDCategory _childEnhancedDCategory : childEnhancedDCategoriesForTops) {
							childEnhancedDCategories.add(_childEnhancedDCategory);// 第二步
																					// 取出所有的子元素
																					// 2
							topIds.add(_childEnhancedDCategory.getEnhancedParentDCategory().getId());
						}
					}
				}

				if (Detect.notEmpty(topIds) && Detect.notEmpty(childEnhancedDCategories)) {
					intersectionCategories = new ArrayList<RCategorySourceQuery.IntersectionCategory>();
					for (long topId : topIds) {
						IntersectionCategory _IntersectionCategory = new IntersectionCategory();
						_IntersectionCategory.setId(topId);
						List<Long> curChildIds = this.getCurChilds(topId, childEnhancedDCategories);
						_IntersectionCategory.setChilds(curChildIds);
						intersectionCategories.add(_IntersectionCategory);
					}
				}
			}

		} else {
			intersectionCategories = new ArrayList<RCategorySourceQuery.IntersectionCategory>();
			List<EnhancedDCategory> topEnhancedDCategories = dCategoryService.getEnhancedTopDCategoriesByItemTypes(returnItemTypes, userContext);
			dCategoryService.appendEnhancedChildDCategories2EnhancedDCategories(topEnhancedDCategories, userContext);
			for (EnhancedDCategory _topEnhancedDCategory : topEnhancedDCategories) {
				IntersectionCategory _IntersectionCategory = new IntersectionCategory();
				_IntersectionCategory.setId(_topEnhancedDCategory.getId());
				_IntersectionCategory.setChilds(this.getCurChilds(_topEnhancedDCategory));
				intersectionCategories.add(_IntersectionCategory);
			}
		}
		return intersectionCategories;
	}

	private List<Long> getCurChilds(EnhancedDCategory topEnhancedDCategory) {
		List<Long> curChildIds = new ArrayList<Long>();
		if (!Detect.notEmpty(topEnhancedDCategory.getEnhancedChildDCategories())) {
			return curChildIds;
		}
		for (EnhancedDCategory _childCategory : topEnhancedDCategory.getEnhancedChildDCategories()) {
			curChildIds.add(_childCategory.getId());
		}

		return curChildIds;
	}

	private List<Long> getCurChilds(long topId, List<EnhancedDCategory> childEnhancedDCategories) {
		List<Long> curChildIds = new ArrayList<Long>();
		for (EnhancedDCategory _EnhancedDCategory : childEnhancedDCategories) {
			if (topId == _EnhancedDCategory.getEnhancedParentDCategory().getId()) {
				curChildIds.add(_EnhancedDCategory.getId());
			}
		}
		return curChildIds;
	}

	@Override
	public List<EnhancedRCategorySource> convent2Enhanceds(List<? extends BasePo> pos) {
		@SuppressWarnings("unchecked")
		List<RCategorySource> rCategorySources = (List<RCategorySource>) pos;
		List<EnhancedRCategorySource> enhancedRCategorySources = new ArrayList<EnhancedRCategorySource>();
		for (RCategorySource _RCategorySource : rCategorySources) {
			enhancedRCategorySources.add(new EnhancedRCategorySource(_RCategorySource));
		}
		return enhancedRCategorySources;
	}

	@Override
	public List<EnhancedRCategorySource> appendEnhancedItem(List<EnhancedRCategorySource> enhancedRCategorySources, UserContext userContext) {
		Map<Class<? extends BasePo>, List<Long>> itemsMap = new HashMap<Class<? extends BasePo>, List<Long>>();

		for (EnhancedRCategorySource _EnhancedRCategorySource : enhancedRCategorySources) {
			List<Long> itemIds = itemsMap.get(_EnhancedRCategorySource.getItemType().getItemClass());
			if (!Detect.notEmpty(itemIds)) {
				itemIds = new ArrayList<Long>();
				itemsMap.put(_EnhancedRCategorySource.getItemType().getItemClass(), itemIds);
			}
			itemIds.add(_EnhancedRCategorySource.getEnhancedItem().getDynamicId());
		}
		Set<Entry<Class<? extends BasePo>, List<Long>>> itemsEntry = itemsMap.entrySet();
		for (Entry<Class<? extends BasePo>, List<Long>> _Entry : itemsEntry) {
			if (Detect.notEmpty(_Entry.getValue())) {
				this.appendEnhancedItem2EnhancedRTagSources(_Entry, enhancedRCategorySources, userContext);
			}
		}
		return enhancedRCategorySources;
	}

	private void appendEnhancedItem2EnhancedRTagSources(Entry<Class<? extends BasePo>, List<Long>> _Entry, List<EnhancedRCategorySource> enhancedRCategorySources, UserContext userContext) {
		try {
			// WebApplicationContext webApplicationContext =
			// ContextLoader.getCurrentWebApplicationContext();

			Class serviceClass = Class.forName("com.jilefojing.service.I" + _Entry.getKey().getSimpleName() + "Service");
			Object interfaceImpl = applicationContext.getBean(serviceClass);

			List<BaseEnhanced> enhancedItems = null;
			for (Method _Method : serviceClass.getMethods()) {
				if (_Method.getName().equals("getEnhanceds")) {
					// enhancedItems = (List<BaseEnhanced>)
					// _Method.invoke(webApplicationContext.getBean(serviceClass),
					// _Entry.getValue(), userContext);
					enhancedItems = (List<BaseEnhanced>) _Method.invoke(interfaceImpl, _Entry.getValue(), userContext);
					break;
				}
			}

			for (EnhancedRCategorySource _EnhancedRCategorySource : enhancedRCategorySources) {
				for (BaseEnhanced _BaseEnhanced : enhancedItems) {
					if (_EnhancedRCategorySource.getItemType().getEnhancedItemClass() == _BaseEnhanced.getClass()
							&& _EnhancedRCategorySource.getEnhancedItem().getDynamicId() == _BaseEnhanced.getDynamicId()) {
						_EnhancedRCategorySource.setEnhancedItem(_BaseEnhanced);
						break;
					}
				}
			}

		} catch (ClassNotFoundException | BeansException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e1) {
			_LOGGER.error("获取资源Service出错", e1);
		}

	}

	@Override
	public void update(RCategorySource rCategorySource, UserContext userContext) throws UserContextException {
		ItemTypeEnumForSource itemType = ItemTypeEnumForSource.getItemTypeEnumByCode(rCategorySource.getItemType());
		StatusEnumForPublish status = StatusEnumForPublish.ALREADY_RELEASED;
		if (rCategorySource.getStatus() != null && StatusEnumForPublish.getStatusEnumByCode(rCategorySource.getStatus()) != null) {
			status = StatusEnumForPublish.getStatusEnumByCode(rCategorySource.getStatus());
		}

		List<RCategorySource> dbRCategorySources = rCategorySourceDao.getListByItem(itemType, rCategorySource.getItemId());
		if (!Detect.notEmpty(dbRCategorySources)) {
			throw new UserContextException("[更新对象不存在]");
		}

		BaseEnhanced enhancedItem = sourceService.getEnhancedItem(itemType, rCategorySource.getItemId(), userContext);
		if (enhancedItem == null) {
			throw new UserContextException(ResponseEnum.SOURCE_NOT_EXIST);
		}
		if (status == StatusEnumForPublish.ALREADY_RELEASED && (StatusEnumForPublish) enhancedItem.get("getStatus") != StatusEnumForPublish.ALREADY_RELEASED) {
			throw new UserContextException(ResponseEnum.SOURCE_INVALID);
		}
		Date now = new Date();
		for (RCategorySource _dbRCategorySource : dbRCategorySources) {
			_dbRCategorySource.setSort(rCategorySource.getSort() == null ? 0 : rCategorySource.getSort());
			_dbRCategorySource.setHotSort(rCategorySource.getHotSort() == null ? 0 : rCategorySource.getHotSort());
			_dbRCategorySource.setStatus(status.getCode());
			_dbRCategorySource.setUpdateTime(now);
		}

		rCategorySourceDao.updateByIds(dbRCategorySources);
	}

	@Override
	public EnhancedRCategorySource getEnhancedByItem(long itemId, ItemTypeEnumForSource itemType, UserContext userContext) {
		List<EnhancedRCategorySource> enhancedRCategorySources = this.getEnhancedsByItems(Arrays.asList(new Long[] { itemId }), itemType, userContext);
		if (!Detect.notEmpty(enhancedRCategorySources)) {
			return null;
		}
		return enhancedRCategorySources.get(0);
	}

	@Override
	public List<EnhancedRCategorySource> getEnhancedsByItems(List<Long> itemIds, ItemTypeEnumForSource itemType, UserContext userContext) {
		List<RCategorySource> rCategorySources = rCategorySourceDao.getListByItems(itemType, itemIds);
		if (!Detect.notEmpty(rCategorySources)) {
			return null;
		}
		List<EnhancedRCategorySource> enhancedRCategorySources = this.convent2Enhanceds(rCategorySources);
		return enhancedRCategorySources;
	}
}
